﻿////Copyright 2012 - Jonathan Allen

//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Diagnostics.Contracts;

//namespace Granite.Time
//{

//    /// <summary>
//    /// A DateTime object with an actual tiem zone
//    /// </summary>
//    public struct DateTimeZone
//    {

//        readonly DateTimeOffset m_DateTimeOffset;
//        readonly TimeZoneInfo m_TimeZone;

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="dateTimeOffset"></param>
//        /// <param name="timeZone"></param>
//        /// <remarks>The dateTimeOffset parameter is adjusted to match the offset indicated by the timeZone parameter</remarks>
//        public DateTimeZone(DateTimeOffset dateTimeOffset, TimeZoneInfo timeZone)
//        {
//            if (timeZone == null)
//                throw new ArgumentNullException("timeZone", "timeZone is null.");
//            Contract.EndContractBlock();

//            m_DateTimeOffset = TimeZoneInfo.ConvertTime(dateTimeOffset, timeZone);
//            m_TimeZone = timeZone;
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="dateTime"></param>
//        /// <param name="timeZone"></param>
//        public DateTimeZone(DateTime dateTime, TimeZoneInfo timeZone)
//        {
//            if (timeZone == null)
//                throw new ArgumentNullException("timeZone", "timeZone is null.");
//            Contract.EndContractBlock();

//            switch (dateTime.Kind)
//            {
//                case DateTimeKind.Local:
//                case DateTimeKind.Utc:
//                    var dateTimeOffset = new DateTimeOffset(dateTime);
//                    m_DateTimeOffset = TimeZoneInfo.ConvertTime(dateTimeOffset, timeZone);
//                    break;

//                case DateTimeKind.Unspecified:
//                default: 
//                    if (timeZone.IsInvalidTime(dateTime))
//                        throw new ArgumentException("The dateTime value " + dateTime + " is not valid in the timeZone " + timeZone);
//                    if (timeZone.IsAmbiguousTime(dateTime))
//                        throw new ArgumentException("The dateTime value " + dateTime + " is not valid in the timeZone " + timeZone);

//                    var offSet = timeZone.GetUtcOffset(dateTime);
//                    m_DateTimeOffset = new DateTimeOffset(dateTime, offSet);
//                    break;

//            }
//            m_TimeZone = timeZone;
//        }

//        ///// <summary>
//        ///// 
//        ///// </summary>
//        //public TimeSpan UtcOffset
//        //{
//        //	get { return TimeZone.GetUtcOffset(DateTimeOffset); }
//        //}

//        /// <summary>
//        /// 
//        /// </summary>
//        public DateTimeOffset DateTimeOffset
//        {
//            get { return m_DateTimeOffset; }
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        public TimeZoneInfo TimeZone
//        {
//            get { return m_TimeZone; }
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <returns></returns>
//        public DateTimeZoneCode ToDateTimeZoneCode()
//        {
//            return new DateTimeZoneCode(m_DateTimeOffset, DateTimeZoneCode.GetTimeZoneCode(TimeZone, TimeZone.IsDaylightSavingTime(DateTimeOffset)));
//        }

//        /// <summary>
//        /// Returns a <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
//        /// </summary>
//        /// <returns>
//        /// A <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
//        /// </returns>
//        /// <filterpriority>2</filterpriority>
//        public override string ToString()
//        {
//            return ToDateTimeZoneCode().ToString();
//        }

//        /// <summary>
//        /// Determines whether the specified <see cref="T:System.Object" /> is equal to the current <see cref="T:System.Object" />.
//        /// </summary>
//        /// <returns>
//        /// true if the specified <see cref="T:System.Object" /> is equal to the current <see cref="T:System.Object" />; otherwise, false.
//        /// </returns>
//        /// <param name="obj">
//        /// The <see cref="T:System.Object" /> to compare with the current <see cref="T:System.Object" />. 
//        /// </param>
//        /// <filterpriority>2</filterpriority>
//        public override bool Equals(object obj)
//        {
//            if (!(obj is DateTimeZone))
//                return false;

//            var t2 = (DateTimeZone)obj;

//            if (m_TimeZone == null && t2.m_TimeZone == null)
//                return true;

//            if (m_TimeZone == null || t2.m_TimeZone == null)
//                return false;

//            return (m_TimeZone == t2.m_TimeZone) && m_DateTimeOffset == t2.m_DateTimeOffset;
			
//        }

//        /// <summary>
//        /// Serves as a hash function for a particular type. 
//        /// </summary>
//        /// <returns>
//        /// A hash code for the current <see cref="T:System.Object" />.
//        /// </returns>
//        /// <filterpriority>2</filterpriority>
//        public override int GetHashCode()
//        {
//            if(m_TimeZone==null)
//                return 0;

//            return m_DateTimeOffset.GetHashCode() ^ m_TimeZone.GetHashCode();
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="t1"></param>
//        /// <param name="t2"></param>
//        /// <returns></returns>
//        public static bool operator ==(DateTimeZone t1, DateTimeZone t2)
//        {
//            if (t1.m_TimeZone == null && t2.m_TimeZone == null)
//                return true;

//            if (t1.m_TimeZone == null || t2.m_TimeZone == null)
//                return false;

//            return (t1.m_TimeZone == t2.m_TimeZone) && t1.m_DateTimeOffset == t2.m_DateTimeOffset;
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="t1"></param>
//        /// <param name="t2"></param>
//        /// <returns></returns>
//        public static bool operator !=(DateTimeZone t1, DateTimeZone t2)
//        {
//            if (t1.m_TimeZone == null && t2.m_TimeZone == null)
//                return false;

//            if (t1.m_TimeZone == null || t2.m_TimeZone == null)
//                return true;

//            return (t1.m_TimeZone != t2.m_TimeZone) || t1.m_DateTimeOffset != t2.m_DateTimeOffset;
//        }

//    }
//}
